/*
 * File Name: httpstuff.h
 *
 * Group Members: Cassie Chin (cassiechin9793@gmail.com)
 *                Stephen Smetana (stephensmetana11@gmail.com)
 *                Logan Widick (logan.widick@gmail.com)
 *
 * File Description: 
 *
 *
 */

#ifndef HTTP_STUFF_H
#define HTTP_STUFF_H
// Size of strings in the HTTPMsg
#define BUFFER_SIZE 1024

//special content length constants
#define CONTENT_LENGTH_NOT_SET -1
#define CHUNKED_LENGTH -2

#define CHUNK_SIZE 256
#define NUMBER_BUFFER_SIZE 256

//error codes for message send and receive
#define FILE_CLOSE -3
#define PARSE_ERROR -4

#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>
/**
 * A HeaderListNode stores a header from http.
 */
typedef struct HeaderListNode {
	char *name;
	char *value;
	struct HeaderListNode *next;
} HeaderListNode;

/**
 * A headerlist stores a list of headers in an http message
 */
typedef struct HeaderList{
	HeaderListNode *head;
	HeaderListNode *tail;
} HeaderList;

/**
 * Keeps track of the http state
 */
typedef enum HTTPState {
	FIRSTLINE = 0,//!< FIRSTLINE
	HEADERS = 1,  //!< HEADERS
	BODY = 2,     //!< BODY
	END = 3,      //!< END
} HTTPState;

/**
 * Stores the required information for a certain response code.
 */
typedef struct HTTPResponseCode {
	/** the numeric (machine-readable) status code) */
	int num;	
	
	/** the human readable code */
	char *desc;
	
	/** whether or not we can have a body */
	bool canHaveBody;
} HTTPResponseCode;

/**
 * Represents the data inside an http message.
 */
typedef struct HTTPMsg{
	/** Whether this is a REQUEST or a RESPONSE */
	bool isRequest;
	
	/** The method of the request */
	char *method;
	
	/** A list of headers and their values */
	HeaderList *headerList;
	
	/** The resource to obtain. */
	char *resource;

	/** The host of the resource. */
	char *host;
	
	/** The port of the resource. */
	char *port;
	
	/** The reason phrase (if a response) */
	char *reasonPhrase;

	/** The version of HTTP to use */
	float version;	
	
	/** The state of the parsing */
	HTTPState state;
	
	/** The status code (responses) */
	int statusCode;
	
	/** the content length we go with */
	int contentLength;
   
	/** Pointer to the file */
	FILE *fileptr;
  
} HTTPMsg;

HeaderList *new_HeaderList();
void delete_HeaderList (HeaderList *list);
void HeaderList_addHeader (HeaderList *list, char *name, char *value);
void HeaderList_addToLastHeader (HeaderList *list, char *value);

HTTPMsg *new_HTTPMsg();
void delete_HTTPMsg (HTTPMsg *msg);
int HTTPMsg_sendMsg(HTTPMsg *msg, FILE *sock_out_filp);
int HTTPMsg_doParsing (HTTPMsg *msg, FILE *sock_fp_in);
char* HTTPMsg_findFilePath(HTTPMsg *msg);

/**
 * \struct FilePointerSet
 * A FilePointerSet contains a read FILE* and a write FILE* for a socket.
 */
typedef struct FilePointerSet {
	FILE *inFile;
	FILE *outFile;
} FilePointerSet;

/**
 * Opens a client connection given the port, ip, and a pointer to a FilePointerSet to be filled
 * @param PORT the port # as a string
 * @param IP the IP address to connect to
 * @param ptrSet the pointer to the FilePointerSet to fill.
 * @return 0 on success, something negative on fail.
 */
int openClientConnection(char *PORT, char *IP, FilePointerSet *ptrSet);

#endif
